package com.yuzhenxin.bookstore.dao;

import com.yuzhenxin.bookstore.domain.Book;
import com.yuzhenxin.bookstore.domain.Order;
import com.yuzhenxin.bookstore.domain.OrderItem;
import com.yuzhenxin.bookstore.tools.commons.CommonUtils;
import com.yuzhenxin.bookstore.tools.jdbc.TxQueryRunner;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class OrderDao {

    private final QueryRunner qr = new TxQueryRunner();

    /**
     * 添加订单
     */
    public void addOrder(Order order) {
        try {
            String sql = "insert into orders values(?,?,?,?,?,?)";
            /*
             * 处理util的Date转换成sql的Timestamp
             */
            Timestamp timestamp = new Timestamp(order.getOrdertime().getTime());
            Object[] params = {order.getOid(), timestamp,
                    order.getTotal(), order.getState(), order.getOwner().getUid(),
                    order.getAddress()};
            qr.update(sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加订单条目
     */
    public void addOrderItemList(List<OrderItem> orderItemList) {
        try {
            String sql = "insert into orderitem values(?,?,?,?,?)";
            Object[][] params = new Object[orderItemList.size()][];
            //给每个orderItem的一维数组赋值
            for (int i = 0; i < orderItemList.size(); i++) {
                OrderItem item = orderItemList.get(i);
                params[i] = new Object[]{item.getIid(), item.getCount(),
                        item.getSubtotal(), item.getOrder().getOid(),
                        item.getBook().getBid()};
            }
            qr.batch(sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 按uid查询订单
     */
    public List<Order> findByUid(String uid) {
        /*
         * 1、通过uid查询当前用户所有List<Order>
         * 2、遍历每个order，为其加载所有的OrderItem
         *
         */
        try {
            String sql = "select * from orders where uid=?";
            List<Order> orderList = qr.query(sql, new BeanListHandler<>(Order.class), uid);

            for (Order order : orderList) {
                loadOrderItem(order);
            }

            return orderList;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加载指定的订单的所有订单条目
     */
    private void loadOrderItem(Order order) throws SQLException {
        String sql = "select * from orderitem i, book b where i.bid=b.bid and oid=?";
        List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler(), order.getOid());
        List<OrderItem> orderItemList = toOrderItemList(mapList);
        order.setOrderItemList(orderItemList);
    }

    /**
     * 把mapList每个map转换成两个对象，并建立关系
     */
    private List<OrderItem> toOrderItemList(List<Map<String, Object>> mapList) {
        List<OrderItem> orderItemList = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            OrderItem item = toOrderItem(map);
            orderItemList.add(item);
        }
        return orderItemList;
    }

    /**
     * 把一个map转换成一个OrderItem对象
     */
    private OrderItem toOrderItem(Map<String, Object> map) {
        OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class);
        Book book = CommonUtils.toBean(map, Book.class);
        orderItem.setBook(book);
        return orderItem;
    }

    /**
     * 加载订单
     */
    public Order load(String oid) {
        try {
            String sql = "select * from orders where oid=?";
            Order order = qr.query(sql, new BeanHandler<>(Order.class), oid);
            loadOrderItem(order);
            return order;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过oid查询订单状态
     */
    public int getStateByOid(String oid) {
        try {
            String sql = "select state from orders where oid=?";
            return qr.query(sql, new ScalarHandler<>(), oid);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改订单状态
     */
    public void updateState(String oid, int state) {
        try {
            String sql = "update orders set state=? where oid=?";
            qr.update(sql, state, oid);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
